﻿using System.IO;
using System.Security.Cryptography;
using EncryptionLib.Util;

namespace EncryptionLib.Encryption
{
    public class EncryptFileHeader
    {
        /// <summary>
        /// Vu-Anh Encryption File Format =))
        /// </summary>
        public const string FILEFORMAT = "VAEF";

        private const string FILEVERSION = "1.0";

        public string FileFormat
        {
            get;
            set;
        }

        public string Version
        {
            get;
            set;
        }

        public SymmetricAlgorithms Algorithm
        {
            get;
            set;
        }

        public CipherMode EncryptCipherMode
        {
            get;
            set;
        }

        public PaddingMode EncryptPaddingMode
        {
            get;
            set;
        }

        public bool Zipped
        {
            get;
            set;
        }

        /// <summary>
        /// Encrypted by receiver's public key.
        /// </summary>
        public byte[] SecretKey
        {
            get;
            set;
        }

        public EncryptFileHeader(SymmetricAlgorithms algo, CipherMode cipherMode, 
            PaddingMode paddingMode, bool zipped, byte[] secretKey)
        {
            this.FileFormat = FILEFORMAT;
            this.Version = FILEVERSION;
            this.Algorithm = algo;
            this.EncryptCipherMode = cipherMode;
            this.EncryptPaddingMode = paddingMode;
            this.Zipped = zipped;
            this.SecretKey = secretKey;
        }

        public EncryptFileHeader()
        {
            this.FileFormat = FILEFORMAT;
        }

        public static void Serialize(EncryptFileHeader header, Stream stream)
        {
            SerializerHelper.WriteString(header.FileFormat, stream);
            SerializerHelper.WriteString(header.Version, stream);
            SerializerHelper.WriteInt((int)header.Algorithm, stream);
            SerializerHelper.WriteInt((int)header.EncryptCipherMode, stream);
            SerializerHelper.WriteInt((int)header.EncryptPaddingMode, stream);
            SerializerHelper.WriteBoolean(header.Zipped, stream);
            SerializerHelper.WriteBytes(header.SecretKey, stream);
        }

        public void Serialize(Stream stream)
        {
            Serialize(this, stream);
        }

        public static EncryptFileHeader Deserialize(Stream stream)
        {
            EncryptFileHeader ret = new EncryptFileHeader();
            ret.FileFormat = SerializerHelper.ReadString(stream);
            
            if(ret.FileFormat.CompareTo(FILEFORMAT) != 0)
            {
                throw new InvalidDataException("File format was not corrected.");
            }

            ret.Version = SerializerHelper.ReadString(stream);
            ret.Algorithm = (SymmetricAlgorithms)SerializerHelper.ReadInt(stream);
            ret.EncryptCipherMode = (CipherMode)SerializerHelper.ReadInt(stream);
            ret.EncryptPaddingMode = (PaddingMode)SerializerHelper.ReadInt(stream);
            ret.Zipped = SerializerHelper.ReadBoolean(stream);
            ret.SecretKey = SerializerHelper.ReadBytes(stream);

            return ret;
        }
    }
}
